package com.sugon.aop;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.annotation.DataFilter;
import com.sugon.entity.SysUserEntity;
import com.sugon.modules.sys.consts.SysDeptConst;
import com.sugon.modules.sys.consts.SysUserConst;
import com.sugon.service.SysUserRoleService;
import com.sugon.utils.Constant;
import com.sugon.utils.RRException;
import com.sugon.utils.ShiroUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * 数据过滤，切面处理类
 *
 * @author YuXD
 * @date 2020-08-03 11:47
 */
@Aspect
@Component
public class DataFilterAspect {

    @Autowired
    private SysUserRoleService sysUserRoleService;

    /**
     * 只用作定义切点，注解注明核心内容
     * 方法体内无需任何实现
     */
    @Pointcut("@annotation(com.sugon.annotation.DataFilter)")
    public void dataFilterCut() {
    }

    /**
     * 前置切点
     *
     * @param point 切点
     * @throws Throwable
     */
    @Before("dataFilterCut()")
    public void dataFilter(JoinPoint point) throws Throwable {
        // 参数不能为空
        Object[] args = point.getArgs();
        if (ArrayUtil.isEmpty(args)) {
            return;
        }
        Object objArgs = args[0];
        if (objArgs instanceof Map) {
            Map queryParam = (Map) objArgs;
            String filterSql = getFilterSQL(point);
            if (StrUtil.isNotEmpty(filterSql)) {
                queryParam.put("filterSql", filterSql);
            }
            return;
        }
        throw new RRException("数据权限接口的参数必须为Map类型，且不能为NULL");
    }

    /**
     * 获取数据过滤的SQL
     * 1、首先根据部门判断
     * 如果用户没有关联部门或者是制造处那么不需要拼接任何过滤sql
     */
    private String getFilterSQL(JoinPoint point) {
        StringBuilder filterSql = new StringBuilder("");
        // 获取注解配置信息
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataFilter dataFilter = signature.getMethod().getAnnotation(DataFilter.class);
        // 部门别名和用户别名都不能为空
        String deptAlias = dataFilter.deptAlias();
        String[] userAlias = dataFilter.userAlias();
        if (StrUtil.isEmpty(deptAlias) && ArrayUtil.isEmpty(userAlias)) {
            return filterSql.toString();
        }
        // 获取当前登录用户所在车间
        String workshopId = getWorkshopId();
        // 只处理车间数据权限
        /*
            由于设备-设备工程处、模具-制造工艺处 需要指导所有车间
            因此不需要数据权限控制
         */
        if (StrUtil.isNotEmpty(workshopId) && !StrUtil.equalsAny(workshopId, SysDeptConst.ZZC_CODE, SysDeptConst.ZZGYC_CODE)) {
            // 特殊角色的用户也不进行数据权限控制
            List<String> userRoleList = getUserRoleList();
            if (!userRoleList.contains(Constant.SUPER_QUERY_ROLE)) {
            /*
                区分是否是领导
                    如果是领导，那么只可以查看自己部门内数据
                    否则，则只查看与自己相关的
             */
                if (isLeader()) {
                    if (StrUtil.isNotEmpty(deptAlias)) {
                        filterSql.append(StrUtil.format(" AND {} LIKE '{}%'", deptAlias, workshopId));
                    }
                } else {
                    // 获取当前用户ID
                    String userId = ShiroUtils.getUserId();
                    if (ArrayUtil.isNotEmpty(userAlias) && StrUtil.isNotEmpty(userId)) {
                        List<String> filterList = CollectionUtil.newArrayList();
                        for (String alias : userAlias) {
                            filterList.add(StrUtil.format("INSTR({},'{}') > 0", alias, userId));
                        }
                        if (filterList.size() > 1) {
                            filterSql.append(StrUtil.format(" AND ({})", CollectionUtil.join(filterList, " OR ")));
                        } else {
                            filterSql.append(StrUtil.format(" AND {}", CollectionUtil.join(filterList, " OR ")));
                        }
                    }
                }
            }
        }
        return filterSql.toString();
    }

    /**
     * 获取父部门ID,一般指的是大部门ID
     *
     * @return
     */
    private String getWorkshopId() {
        String deptId = ShiroUtils.getDeptId();
        if (StrUtil.isNotEmpty(deptId) && deptId.length() >= 4) {
            return deptId.substring(0, 4);
        }
        return null;
    }

    /**
     * 返回当前登录用户是否是领导
     * 如果是返回true,否则返回false
     *
     * @return
     */
    private boolean isLeader() {
        SysUserEntity currentUser = ShiroUtils.getUserEntity();
        if (currentUser != null) {
            return SysUserConst.IS_LEADER == currentUser.getLeader();
        }
        return false;
    }

    /**
     * 获取当前用户的角色列表
     *
     * @return
     */
    private List<String> getUserRoleList() {
        SysUserEntity currentUser = ShiroUtils.getUserEntity();
        if (currentUser != null) {
            return sysUserRoleService.queryRoleIdList(currentUser.getUserId());
        }
        return CollectionUtil.newArrayList();
    }

}
